﻿using Microsoft.Office.InfoPath;
using System.Text.RegularExpressions;

namespace InfoPathHelpers.Validation
{
    /// <summary>
    /// Provides a number of methods for validating different data types.
    /// Note: These methods should only be called from a validation event.
    /// </summary>
    public static partial class ValidationHelper
    {
        //const string EMAIL_REGEX = @"([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)";
        const string EMAIL_REGEX = @"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$";

        /// <summary>
        /// Provides validation email addresses stored in a string field.
        /// </summary>
        /// <param name="eventArgs">The XmlValidatingEventArgs of the validation event</param>
        /// <returns>True if the field contained a valid email address; otherwise false.</returns>
        public static bool IsEmail(XmlValidatingEventArgs eventArgs)
        {
            return IsEmail(eventArgs, false, false);
        }

        /// <summary>
        /// Provides validation email addresses stored in a string field
        /// with the option to show dialog to the user for failures.
        /// </summary>
        /// <param name="eventArgs">The XmlValidatingEventArgs of the validation event</param>
        /// <param name="allowBlanks">A boolean value indicating whether or not the field can be empty.</param>
        /// <param name="showDialog">A boolean value indicating whether or not to show the user a message on validation failure.</param>
        /// <returns>True if the field contained a valid email address; otherwise false.</returns>
        public static bool IsEmail(XmlValidatingEventArgs eventArgs, bool allowBlanks, bool showDialog)
        {
            return IsEmail(eventArgs, allowBlanks, showDialog,
                new ValidationMessage()
                {
                    Caption = "Invalid Entry",
                    Message = "Invalid email address entered.",
                    MessageDetails = "This field allows valid email addresses only.",
                },
                new ValidationMessage()
                {
                    Caption = "Blank Entry",
                    Message = "Cannot be blank.",
                    MessageDetails = "This field allows valid email addresses only.",
                }
            );
        }

        /// <summary>
        /// Provides validation email addresses stored in a string field
        /// with the option to show a custom dialog to the user for failures.
        /// </summary>
        /// <param name="eventArgs">The XmlValidatingEventArgs of the validation event</param>
        /// <param name="allowBlanks">A boolean value indicating whether or not the field can be empty.</param>
        /// <param name="showDialog">A boolean value indicating whether or not to show the user a message on validation failure.</param>
        /// <param name="blankMessage">The message to show for blank fields if not allowed.</param>
        /// <param name="invalidMessage">The message to show for fields do not contain a valid email address.</param>
        /// <returns>True if the field contained a valid email address; otherwise false.</returns>
        public static bool IsEmail(XmlValidatingEventArgs eventArgs, bool allowBlanks, bool showDialog, ValidationMessage invalidMessage, ValidationMessage blankMessage)
        {
            if (eventArgs.Operation == XmlOperation.Delete || eventArgs.Operation == XmlOperation.None)
                // Delete operations or unspecififed operations are not validated so just return true.
                return true;

            // Insert operations do not use the New/OldValue parameters of XmlValidatingEventArgs
            // so we need to use the Value of the underlying xml element.
            string Value = eventArgs.Site.Value;

            bool IsEmpty = string.IsNullOrEmpty(Value);
            bool IsValidEmail = IsEmpty ? false : Regex.IsMatch(Value, EMAIL_REGEX);

            if (!IsEmpty && !IsValidEmail)
            {
                // If the field is not empty and the value is not a valid email address then validation has failed.
                // So we report failure using "invalidMessage".
                HandleValidationFailure(eventArgs, invalidMessage, showDialog);
                // And of course return false because validation failed.
                return false;
            }
            else if (IsEmpty && !allowBlanks)
            {
                // If the value is empty but validation does not allow blanks then validation fails.
                // So we report failure using the "blankMessage".
                HandleValidationFailure(eventArgs, blankMessage, showDialog);
                // And of course return false because validation failed.
                return false;
            }

            // Otherwise either the field is empty or a valid email addresss so validation succeeded.
            return true;
        }
    }
}
